package tc.de.krawallmann.robobridge.visualization;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;

import javax.swing.JLabel;
import javax.swing.JPanel;

import eu.hansolo.steelseries.extras.Led;
import eu.hansolo.steelseries.gauges.Linear;
import eu.hansolo.steelseries.gauges.Radial;
import eu.hansolo.steelseries.tools.BackgroundColor;
import eu.hansolo.steelseries.tools.BackgroundImageFactory;
import eu.hansolo.steelseries.tools.ColorDef;
import eu.hansolo.steelseries.tools.ForegroundType;
import eu.hansolo.steelseries.tools.FrameDesign;
import eu.hansolo.steelseries.tools.FrameEffect;
import eu.hansolo.steelseries.tools.KnobType;
import eu.hansolo.steelseries.tools.LcdColor;
import eu.hansolo.steelseries.tools.LedColor;
import eu.hansolo.steelseries.tools.NumberFormat;
import eu.hansolo.steelseries.tools.Section;
import tc.de.krawallmann.robobridge.RoboBridge;
import tc.de.krawallmann.robobridge.communication.AbstractCommunicationInterface;
import tc.de.krawallmann.robobridge.communication.AbstractRemoteCommunicationDevice;
import tc.de.krawallmann.robobridge.communication.ConnectionListener;
import tc.de.krawallmann.robobridge.devices.AbstractDevice;
import tc.de.krawallmann.robobridge.devices.implementation.M256;
import tc.de.krawallmann.robobridge.devices.implementation.RNControl;
import tc.de.krawallmann.robobridge.devices.implementation.RP6Base;
import tc.de.krawallmann.robobridge.util.BitOperations;

public class M256Frame extends AbstractRoboViewDisplay implements ConnectionListener {

	private Radial rssi;
	private Led l1;
	private Led l2;
	private Led l3;
	private Led l4;
	private M256 m256;
	private boolean connected;
	private Led k1;
	private Led k2;
	//TODO LAYOUT
	public M256Frame(RoboBridge bridge, M256 m256) {
		super("RP6 M256 @"+m256.getDeviceId(), false, true, false, true);
		this.m256 = m256;
        bridge.getCommunicationInterface().addConnectionListener(this);
        setLayout(null);
        FrameDesign design = FrameDesign.SHINY_METAL;
		rssi = new Radial();
		if(bridge.isConnected()){
			rssi.setUserLedOn(true);
			connected=true;
		}
		rssi.setForegroundType(ForegroundType.FG_TYPE1);
		rssi.setBackgroundColor(BackgroundColor.DARK_GRAY);
		rssi.setFrameDesign(design);
		rssi.setHighlightArea(true);
		rssi.setDoubleBuffered(true);
		rssi.setFocusable(false);
		rssi.setFrameEffect(FrameEffect.EFFECT_INNER_FRAME);
		rssi.setKnobType(KnobType.METAL_KNOB);
		rssi.setLcdColor(LcdColor.BLUE2_LCD);
		rssi.setMinValue(-100);
		rssi.setMajorTickSpacing(10.0);
		rssi.setMaxValue(0);
		rssi.setTitle("RSSI");
		rssi.setTrackStop(250.0);
		rssi.setUnitString("dBm");
		rssi.setLedVisible(true);
		rssi.setUserLedColor(LedColor.GREEN);
		rssi.setUserLedVisible(true);
		rssi.setSectionsVisible(true);
		rssi.setSection3DEffectVisible(true);
		rssi.setAreasVisible(true);
		//rssi.setArea3DEffectVisible(true);
		rssi.setLcdUnitString("dBm");
		rssi.setLcdUnitStringVisible(true);
		rssi.setValue(-100);
		rssi.setToolTipText("<html>Shows the RN-171's RSSI (Received Signal Strength Indication).<br/>A value of -100dBm means that the module is not connected!");

		rssi.addSection(new Section(-50, 0, Color.GREEN));
		rssi.addSection(new Section(-100, -60, Color.RED));
		rssi.addSection(new Section(-60, -50, Color.ORANGE));

		rssi.addArea(new Section(-100, -60, Color.RED));
		rssi.setBounds(50, 0, 200, 200);
		add(rssi);
       //TODO LAYOUT
		JPanel LEDPanel = new JPanel(new GridLayout(2, 4));
		LEDPanel.setBounds(0, 210, 300, 60);
		l1 = new Led();
		l1.setLedColor(LedColor.RED);
		LEDPanel.add(l1);
		l2 = new Led();
		l2.setLedColor(LedColor.RED);
		LEDPanel.add(l2);
		l3 = new Led();
		l3.setLedColor(LedColor.RED);
		LEDPanel.add(l3);
		l4 = new Led();
		l4.setLedColor(LedColor.RED);
		LEDPanel.add(l4);
		
		JLabel jl1 = new JLabel("LED1", JLabel.CENTER);
		jl1.setForeground(Color.white);
		LEDPanel.add(jl1);
		JLabel jl2 = new JLabel("LED2", JLabel.CENTER);
		jl2.setForeground(Color.white);
		LEDPanel.add(jl2);
		JLabel jl3 = new JLabel("LED3", JLabel.CENTER);
		jl3.setForeground(Color.white);
		LEDPanel.add(jl3);
		JLabel jl4 = new JLabel("LED4", JLabel.CENTER);
		jl4.setForeground(Color.white);
		LEDPanel.add(jl4);

		
		LEDPanel.setOpaque(false);
		add(LEDPanel);
		
		JPanel keyPanel = new JPanel(new GridLayout(2, 2));
		keyPanel.setBounds(0, 270, 300, 60);
		k1 = new Led();
		k1.setLedColor(LedColor.GREEN);
		keyPanel.add(k1);
		k2 = new Led();
		k2.setLedColor(LedColor.GREEN);
		keyPanel.add(k2);
	
		
		JLabel kl1 = new JLabel("Key1", JLabel.CENTER);
		kl1.setForeground(Color.white);
		keyPanel.add(kl1);
		JLabel kl2 = new JLabel("Key2", JLabel.CENTER);
		kl2.setForeground(Color.white);
		keyPanel.add(kl2);
		keyPanel.setOpaque(false);
		add(keyPanel);

		setSize(310, 370);
		setVisible(true);
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = -2118047100671278658L;

	@Override
	public void onSensorValueChanged(AbstractDevice sensor, String propertyName, Object oldValue,
			Object newValue) {
		if (sensor.equals(m256)) {
			if(connected&&propertyName.equals(M256.RSSI)){
				rssi.setValue((Integer)newValue);
			}else if (propertyName.equals(M256.M256_LEDS)) {
				if (BitOperations.isBitSet((Integer) newValue, 0)) {
					l1.setLedOn(true);
				} else {
					l1.setLedOn(false);
				}
				if (BitOperations.isBitSet((Integer) newValue, 1)) {
					l2.setLedOn(true);
				} else {
					l2.setLedOn(false);
				}
				if (BitOperations.isBitSet((Integer) newValue, 2)) {
					l3.setLedOn(true);
				} else {
					l3.setLedOn(false);
				}
				if (BitOperations.isBitSet((Integer) newValue, 3)) {
					l4.setLedOn(true);
				} else {
					l4.setLedOn(false);
				}
			}else if(propertyName.equals(M256.M256_KEY)){
				switch(m256.getPressedKey()){
					case 1:{
						k1.setLedOn(true);
						k2.setLedOn(false);
						break;
					}
					case 2:{
						k1.setLedOn(false);
						k2.setLedOn(true);
						break;
					}
					default:{
						k1.setLedOn(false);
						k2.setLedOn(false);
					}
				}
			}
		}
	}

	@Override
	public void onConnect(AbstractRemoteCommunicationDevice device) {
		rssi.setValue(-100);
		connected=true;
		rssi.setUserLedOn(true);
	}

	@Override
	public void onDisconnect(AbstractRemoteCommunicationDevice device, int reason) {
		rssi.setValue(-100);
		connected=false;
		if(reason==AbstractCommunicationInterface.ERROR){
			rssi.setLedBlinking(true);
		}
		rssi.setUserLedOn(false);
	}

}
